{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Log模块资料\n",
    "- https://www.cnblogs.com/yyds/p/6901864.html"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Python语言的高级特性\n",
    "## 函数式编程（FunctionalProgramming)\n",
    "- 基于lambda演算的一种编程方式\n",
    "    - 程序中只有函数\n",
    "    - 函数可以作为函数，同样可以作为返回值\n",
    "    - 纯函数式编程语言：LISP，Haskell\n",
    "    \n",
    "- Python函数式编程知识借鉴函数式编程的一些特点，可以理解成一半函数式一半python\n",
    "- 需要讲述\n",
    "    - 高阶函数\n",
    "    - 返回函数\n",
    "    - 匿名函数\n",
    "    - 装饰器\n",
    "    - 偏函数"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### lambda表达式\n",
    "- 函数：最大程度复用代码\n",
    "    -存在问题：如果函数很小，很短，则会造成啰嗦\n",
    "    - 如果函数被调用次数少，则会造成浪费\n",
    "    - 对于阅读者来说，造成阅读流程的被迫中断\n",
    "    \n",
    "- lambda表达式（匿名函数）：\n",
    "    - 一个表达式，函数体相对简单\n",
    "    - 不是一个代码块，仅仅是一个表达式\n",
    "    - 可以有参数，有多个参数也可以，用逗号隔开"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "AAAAA\n"
     ]
    }
   ],
   "source": [
    "# 小函数举例\n",
    "def printA():\n",
    "    print('AAAAA')\n",
    "    \n",
    "printA()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "200"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# lambda表达式用法\n",
    "# 1.以lambda开头\n",
    "# 2.紧跟一定的参数（如果有的话）\n",
    "# 3.参数后用冒号和表达式主体隔开\n",
    "# 4.只是一个表达式，所以，没有return\n",
    "\n",
    "stm = lambda x : 100 * x\n",
    "stm(2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "432"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "stm2 = lambda x,y,z : x + y * 10 + z * 100\n",
    "stm2(2,3,4)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 高阶函数\n",
    "- 把函数作为参数使用的函数，叫高阶函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "in funA\n"
     ]
    }
   ],
   "source": [
    "# 函数名称就是一个变量\n",
    "def funA():\n",
    "    print('in funA')\n",
    "    \n",
    "funB = funA\n",
    "funB()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 以上代码得出的结论：\n",
    "- 函数名称是变量\n",
    "- funB 和funA只是名称不一样而已\n",
    "- 既然函数名称是变量，则应该可以被当作参数传入另一个函数\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "900\n",
      "900\n"
     ]
    }
   ],
   "source": [
    "# 高阶函数举例\n",
    "# funA是普通函数，返回一个传入数字的100倍\n",
    "\n",
    "def funA(n):\n",
    "    return n * 100\n",
    "\n",
    "# 再写一个函数，把传入参数乘以300\n",
    "\n",
    "def funB(n):\n",
    "    return funA(n) * 3\n",
    "\n",
    "print(funB(3))\n",
    "\n",
    "# 写一个高阶函数\n",
    "def funC(n, f):\n",
    "    # 假定函数是把n扩大100倍\n",
    "    return f(n) * 3\n",
    "\n",
    "print(funC(3, funA))\n",
    "    "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 系统高阶函数 -map\n",
    "- 原意就是映射，即把集合或者列表的元素，每一个元素都按照一定规则进行操作，生成一个新的列表或者集合\n",
    "- map函数是系统提供的具有映射功能的函数，返回值是一个迭代对象"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "collapsed": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0, 10, 20, 30, 40, 50, 60, 70, 80, 90]\n",
      "<map object at 0x10a294908>\n",
      "0\n",
      "10\n",
      "20\n",
      "30\n",
      "40\n",
      "50\n",
      "60\n",
      "70\n",
      "80\n",
      "90\n"
     ]
    }
   ],
   "source": [
    "# map举例\n",
    "# 有一个列表，相对列表里的每一个元素乘以10，并得到新的列表\n",
    "\n",
    "l1 = [i for i in range(10)]\n",
    "l2 = []\n",
    "for i in l1:\n",
    "    l2.append(i * 10)\n",
    "print(l2)\n",
    "\n",
    "# 利用map实现\n",
    "\n",
    "def mulTen(n):\n",
    "    return n * 10\n",
    "\n",
    "l3 = map(mulTen, l1)\n",
    "print(l3)\n",
    "# map类型是一个可迭代的结构，所以可以使用for循环遍历\n",
    "for i in l3:\n",
    "    print(i)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# reduce\n",
    "- 原意是归并，缩减\n",
    "- 把一个可迭代对象最后归并成一个结果\n",
    "- 对于作为参数的函数有要求：必须有两个参数，必须有返回结果\n",
    "- reduce( [1,2,3,4,5] == f( f (f (f(1,2),3),4),5)\n",
    "- reduce 需要导入functools包"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "21\n"
     ]
    }
   ],
   "source": [
    "from functools import reduce\n",
    " # 定义一个操作函数\n",
    "# 假如操作函数只是相加运算\n",
    "\n",
    "def myAdd(x,y):\n",
    "    return x + y\n",
    "# 对于列表[1,2,3,4,5,6]执行myAdd的reduce操作\n",
    "rst = reduce( myAdd, [1,2,3,4,5,6])\n",
    "print(rst)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
